/**
 * Created by liangshan on 14-11-26.
 * Last Modified by liangshan on 14-11-26.
 */
;
var LsSlider = (function(){
    'use strict';
    var bodyWidth = document.body.scrollWidth,
        bodyHeight = document.body.scrollHeight;

    var wrapper = document.querySelector("#lsSliderWrapper");

// 是否允许翻页。
    var allowSlide = true;

// 翻页动画的过渡时间。
    var $DURATION = 600;

// 是否完成翻页。
    var slideChangeFinished = false;

    var $scene1 = document.querySelector(".scene1"),
        $scenes = document.querySelectorAll(".scene");
    var updateElementTransform = function(_target, _left, _top, _duration, callback) {
        _target.style.transform = "translate("+_left+"px, "+_top+"px)";
        _target.style.webkitTransform = "translate("+_left+"px, "+_top+"px)";
        _target.style.mozTransform = "translate("+_left+"px, "+_top+"px)";
        _target.style.oTransform = "translate("+_left+"px, "+_top+"px)";

        if(typeof _duration === "number") {
            if(callback) {
                updateElementTransition(_target, _duration, callback);
            }
            else {
                updateElementTransition(_target, _duration);
            }
        }
    };

    var updateElementTransition = function (_target, _duration, callback) {
        _target.style.transition = "transform " + _duration + "ms cubic-bezier(0.645,0.045,0.355,1)";
        _target.style.webkitTransition = "-webkit-transform " + _duration + "ms cubic-bezier(0.645,0.045,0.355,1)";
        _target.style.mozTransition = "-moz-transform " + _duration + "ms cubic-bezier(0.645,0.045,0.355,1)";
        _target.style.oTransition = "-o-transform " + _duration + "ms cubic-bezier(0.645,0.045,0.355,1)";
        if(callback) {
            setTimeout(function () {
                callback();
            }, _duration);
        }
    };

    /**
     * Extend object a with the properties of object b.
     * If there's a conflict, object b takes precedence.
     */
    function extend( a, b ) {

        for( var i in b ) {
            a[ i ] = b[ i ];
        }

    }

    /**
     * Dispatches an event of the specified type from the
     * reveal DOM element.
     */
    function dispatchEvent( type, properties) {

        var event = document.createEvent( "HTMLEvents", 1, 2 );
        event.initEvent( type, true, true );
        extend( event, properties );
        wrapper.dispatchEvent( event );
    }

    //var updateElementTransition = function (_target, _duration, callback) {
    //    _target.style.transition = "transform "+_duration/1000+"s cubic-bezier(.43,0,.25,1)";
    //    _target.style.webkitTransition = "-webkit-transform "+_duration/1000+"s cubic-bezier(.43,0,.25,1)";
    //    _target.style.mozTransition = "-moz-transform "+_duration/1000+"s cubic-bezier(.43,0,.25,1)";
    //    _target.style.oTransition = "-o-transform "+_duration/1000+"s cubic-bezier(.43,0,.25,1)";
    //
    //    if(callback) {
    //        setTimeout(function () {
    //            callback();
    //        }, _duration);
    //    }
    //};
    //var updateElementTransform = function(_target, _left, _top, _duration, callback) {
    //    _target.style.transform = "translate3d("+_left+"px, "+_top+"px, 0px)";
    //    _target.style.webkitTransform = "translate3d("+_left+"px, "+_top+"px, 0px)";
    //    _target.style.mozTransform = "translate3d("+_left+"px, "+_top+"px, 0px)";
    //    _target.style.oTransform = "translate3d("+_left+"px, "+_top+"px, 0px)";
    //
    //    if(typeof _duration === "number") {
    //        if(callback) {
    //            updateElementTransition(_target, _duration, callback);
    //        }
    //        else {
    //            updateElementTransition(_target, _duration);
    //        }
    //    }
    //};
    var clearElementTransition = function (_target) {
        _target.style.transition = "";
        _target.style.webkitTransition = "";
        _target.style.mozTransition = "";
        _target.style.oTransition = "";
    };

    var init = function (_indexh, _swipeLeft) {
        var $stages = $scenes[_indexh].querySelectorAll(".stage");
        for(var j = 0; j < $stages.length; j++) {
            if(j === 0) {
                if(_indexh === 0) {
                    updateElementTransform($stages[j], -bodyWidth, 0);
                }
                else {
                    if(_swipeLeft) {
                        updateElementTransform($stages[j], bodyWidth, 0);
                    }
                    else {
                        updateElementTransform($stages[j], -bodyWidth, 0);
                    }
                }
            }
            else {
                updateElementTransform($stages[j], 0, bodyHeight);
            }
            clearElementTransition($stages[j]);
        }
    };

    var $HORIZONTAL = 0,
        $VERTICAL = 0;

// 所有横向页面。
    var horizontalSlides = document.querySelectorAll("#lsSliderWrapper>section");

    var getVerticalSlide = function (_indexh) {
        "use strict";
        return horizontalSlides[_indexh].getElementsByTagName("section");
    };

    var getElementBySlideIndex = function (_indexh, _indexv) {
        return horizontalSlides[_indexh].getElementsByTagName("section")[_indexv];
    };

    var getHorizontal = function() {
            return $HORIZONTAL;
        },
        getVertical = function () {
            return $VERTICAL;
        };

    var goNextVertical = function (_indexh, _indexv, _duration, callback) {
            var verticalSlides = getVerticalSlide(_indexh);

            if(_indexv >= verticalSlides.length - 1) {
                return;
            }
            else {
                // 翻到纵向的下一页。
                var currentSlide = getElementBySlideIndex(_indexh, _indexv),
                    nextSlide = getElementBySlideIndex(_indexh, _indexv + 1);

                currentSlide.classList.remove("active");
                nextSlide.classList.add("active");
                updateElementTransform(currentSlide, 0, -bodyHeight, _duration);
                updateElementTransform(nextSlide, 0, 0, _duration);

                $VERTICAL += 1;
                setTimeout(function () {
                    if(callback) {
                        callback();
                    }
                    slideChangeFinished = true;
                    if(slideChangeFinished) {
                        dispatchEvent( 'slidechanged', {
                            'indexh': $HORIZONTAL,
                            'indexv': $VERTICAL,
                            'lastVertical': getVerticalSlide($HORIZONTAL).length - 1,
                            'direction': $direction,
                            'setTouchEndDelay': function(_delay){
                                setTouchEndDelay(_delay);
                            }
                        } );
                    }
//                        alert(getHorizontal() + ", " + getVertical());
                }, _duration);
            }
        },
        goPrevVertical = function (_indexh, _indexv, _duration, callback) {
            if(_indexv === 0) {
                return;
            }
            else {
                // 翻到纵向的上一页。
                var currentSlide = getElementBySlideIndex(_indexh, _indexv),
                    prevSlide = getElementBySlideIndex(_indexh, _indexv - 1);

                currentSlide.classList.remove("active");
                prevSlide.classList.add("active");
                updateElementTransform(currentSlide, 0, bodyHeight, _duration);
                updateElementTransform(prevSlide, 0, 0, _duration);
                $VERTICAL -= 1;
                setTimeout(function () {
                    if(callback) {
                        callback();
                    }
                    slideChangeFinished = true;
                    if(slideChangeFinished) {
                        dispatchEvent( 'slidechanged', {
                            'indexh': $HORIZONTAL,
                            'indexv': $VERTICAL,
                            'lastVertical': getVerticalSlide($HORIZONTAL).length - 1,
                            'direction': $direction,
                            'setTouchEndDelay': function(_delay){
                                setTouchEndDelay(_delay);
                            }
                        } );
                    }
//                        alert(getHorizontal() + ", " + getVertical());
                }, _duration);
            }
        },
        goNextHorizontal = function (_indexh, _indexv, _duration, callback) {
            if(_indexh >= horizontalSlides.length - 1) {
                return;
            }
            else {
                // 翻到横向的下一页。
                var currentSlide = getElementBySlideIndex(_indexh, _indexv),
                    nextSlide = getElementBySlideIndex(_indexh + 1, 0);
                updateElementTransform(currentSlide, -bodyWidth, 0, _duration);
                updateElementTransform(nextSlide, 0, 0, _duration);
                $HORIZONTAL += 1;
                $VERTICAL = 0;
                setTimeout(function () {
                    init($HORIZONTAL-1);
                    if(callback) {
                        callback();
                    }
                    slideChangeFinished = true;
                    if(slideChangeFinished) {
                        dispatchEvent( 'slidechanged', {
                            'indexh': $HORIZONTAL,
                            'indexv': $VERTICAL,
                            'lastVertical': getVerticalSlide($HORIZONTAL).length - 1,
                            'direction': $direction,
                            'setTouchEndDelay': function(_delay){
                                setTouchEndDelay(_delay);
                            }
                        } );
                    }
//                        alert(getHorizontal() + ", " + getVertical());
                }, _duration);
            }
        },
        goPrevHorizontal = function (_indexh, _indexv, _duration, callback) {
            if(_indexh === 0) {
                return;
            }
            else {
                // 翻到横向的前一页。
                var currentSlide = getElementBySlideIndex(_indexh, _indexv),
                    prevSlide = getElementBySlideIndex(_indexh - 1, 0);

                updateElementTransform(currentSlide, bodyWidth, 0, _duration);
                updateElementTransform(prevSlide, 0, 0, _duration);
                $HORIZONTAL -= 1;
                $VERTICAL = 0;
                setTimeout(function () {
                    init($HORIZONTAL+1, true);
                    if(callback) {
                        callback();
                    }
                    slideChangeFinished = true;
                    if(slideChangeFinished) {
                        dispatchEvent( 'slidechanged', {
                            'indexh': $HORIZONTAL,
                            'indexv': $VERTICAL,
                            'lastVertical': getVerticalSlide($HORIZONTAL).length - 1,
                            'direction': $direction,
                            'setTouchEndDelay': function(_delay){
                                setTouchEndDelay(_delay);
                            }
                        } );
                    }
//                        alert(getHorizontal() + ", " + getVertical());
                }, _duration);
            }
        },
        slideTo = function (_indexh, _indexv, _direction, _duration) {
            var currentSlide = getElementBySlideIndex($HORIZONTAL, $VERTICAL),
                futureSlide = getElementBySlideIndex(_indexh, _indexv);

            switch (_direction) {
                case 1:
                    updateElementTransform(currentSlide, 0, -bodyHeight, _duration);
                    break;
                case 2:
                    updateElementTransform(currentSlide, bodyWidth, 0, _duration);
                    break;
                case 3:
                    updateElementTransform(currentSlide, 0, bodyHeight, _duration);
                    break;
                case 4:
                    updateElementTransform(currentSlide, -bodyWidth, 0, _duration);
                    break;
                default :
                    break;
            }
            updateElementTransform(futureSlide, 0, 0, _duration);
            $HORIZONTAL = _indexh;
            $VERTICAL = _indexv;
        };

    var resetSlide = function (_indexh, _indexv) {
        if(_indexh === 0 && _indexv === 0) {

        }
        else {
            var slide = getElementBySlideIndex(_indexh, _indexv);
            slide.style.opacity = 0;
            if(_indexv === 0) {
                slide.style.transform = "translate("+bodyWidth+"px, 0px)";
                slide.style.webkitTransform = "translate("+bodyWidth+"px, 0px)";
                slide.style.mozTransform = "translate("+bodyWidth+"px, 0px)";
                slide.style.oTransform = "translate("+bodyWidth+"px, 0px)";
            }
            else {
                slide.style.transform = "translate(0px, "+bodyHeight+"px)";
                slide.style.webkitTransform = "translate(0px, "+bodyHeight+"px)";
                slide.style.mozTransform = "translate(0px, "+bodyHeight+"px)";
                slide.style.oTransform = "translate(0px, "+bodyHeight+"px)";
            }
            setTimeout(function () {
                slide.style.opacity = 1;
            }, $DURATION);
        }
    };

    var startX,
        endX,
        startY,
        endY,
        startTime,
        endTime,
        $touch,
        touchEndWithoutMove = true;
// 是否禁止滑动。在touchend到一次touch之间有一个禁止滑动的间隔。
    var disableSlide = false;
// $direction表示滑动的方向。0为无滑动、1为向上滑动、2为向右滑动、3为向下滑动、4为向左滑动。
    var $direction = 0;

    var beginSlide = false;

    // touchend延迟执行的时间。单位ms。
    var touchEndDelay = 50;
    // 设置touchend延迟执行。
    var setTouchEndDelay = function (_delay) {
        touchEndDelay = _delay;
        //return touchEndDelay;
    };

    // 页面开始滑动。
    var startSlide = false;
    var enableStartSlide = function () {
        startSlide = true;
    };

    var _start = function (evt) {
            evt.preventDefault();
            $touch = evt.changedTouches[0];
            startX = $touch.clientX;
            startY = $touch.clientY;
            startTime = evt.timeStamp;

        },
        _move = function (evt) {
            evt.preventDefault();
            touchEndWithoutMove = false;
            if(disableSlide) {
                evt.preventDefault();
            }
            else {
                //dispatchEvent( 'beforeslide', {
                //    'indexh': $HORIZONTAL,
                //    'indexv': $VERTICAL,
                //    'direction': $direction,
                //    'setTouchEndDelay': function(_delay){
                //        setTouchEndDelay(_delay);
                //    }
                //} );
            }
        },
        _end = function (evt) {

            if(disableSlide || touchEndWithoutMove) {
                evt.preventDefault();
            }
            else {
                disableSlide = true;
                $touch = evt.changedTouches[0];
                endX = $touch.clientX;
                endY = $touch.clientY;
                endTime = evt.timeStamp;

                if(Math.abs(endX - startX) < Math.abs(endY - startY) && Math.abs(endY - startY) > 5) {
                    if(endY > startY) {
                        if($CurrentV <= 0) {
                            $direction = 0;
                        }
                        else {
                            $direction = 3;
                        }
                    }
                    else {
                        if($CurrentV >= getVerticalSlide($CurrentH).length - 1) {
                            $direction = 0;
                        }
                        else {
                            $direction = 1;
                        }
                    }
                }
                else if(Math.abs(endX - startX) >= Math.abs(endY - startY) && Math.abs(endX - startX) > 5) {
                    if(endX > startX) {
                        if($CurrentH >= horizontalSlides.length - 1) {
                            $direction = 0;
                        }
                        else {
                            $direction = 4;
                        }
                    }
                    else {
                        if($CurrentH <= 0) {
                            $direction = 0;
                        }
                        else {
                            $direction = 2;
                        }
                    }
                }
                else {
                    $direction = 0;
                }

                //dispatchEvent( 'slided', {
                //    'indexh': $HORIZONTAL,
                //    'indexv': $VERTICAL
                //} );

                dispatchEvent( 'beforeslide', {
                    'indexh': $HORIZONTAL,
                    'indexv': $VERTICAL,
                    'direction': $direction,
                    'setTouchEndDelay': function(_delay){
                        setTouchEndDelay(_delay);
                    }
                } );
                setTimeout(function () {
                    slide();
                    setTimeout(function () {
                        disableSlide = false;
                    }, ($DURATION + touchEndDelay)*2);
                }, touchEndDelay);
            }
            touchEndWithoutMove = true;
        };
    
    var slide = function () {
        //if(_direction) {
        //    switch (_direction) {
        //        case 0:
        //            break;
        //        case 1:
        //            // 向上滑动。
        //            $VERTICAL += 1;
        //            goNextVertical($HORIZONTAL, $VERTICAL, $DURATION);
        //
        //            break;
        //        case 2:
        //            // 向右滑动。
        //            goNextHorizontal($HORIZONTAL, $VERTICAL, $DURATION);
        //            break;
        //        case 3:
        //            // 向下滑动。
        //            $VERTICAL -= 1;
        //            goPrevVertical($HORIZONTAL, $VERTICAL, $DURATION);
        //            break;
        //        case 4:
        //            // 向左滑动。
        //            goPrevHorizontal($HORIZONTAL, $VERTICAL, $DURATION);
        //            break;
        //        default :
        //            break;
        //    }
        //}
        //else {
        //    switch ($direction) {
        //        case 0:
        //            break;
        //        case 1:
        //            // 向上滑动。
        //            goNextVertical($HORIZONTAL, $VERTICAL, $DURATION);
        //            break;
        //        case 2:
        //            // 向右滑动。
        //            goNextHorizontal($HORIZONTAL, $VERTICAL, $DURATION);
        //            break;
        //        case 3:
        //            // 向下滑动。
        //            goPrevVertical($HORIZONTAL, $VERTICAL, $DURATION);
        //            break;
        //        case 4:
        //            // 向左滑动。
        //            goPrevHorizontal($HORIZONTAL, $VERTICAL, $DURATION);
        //            break;
        //        default :
        //            break;
        //    }
        //}
        switch ($direction) {
            case 0:
                break;
            case 1:
                // 向上滑动。
                goNextVertical($HORIZONTAL, $VERTICAL, $DURATION);
                break;
            case 2:
                // 向右滑动。
                goNextHorizontal($HORIZONTAL, $VERTICAL, $DURATION);
                break;
            case 3:
                // 向下滑动。
                goPrevVertical($HORIZONTAL, $VERTICAL, $DURATION);
                break;
            case 4:
                // 向左滑动。
                goPrevHorizontal($HORIZONTAL, $VERTICAL, $DURATION);
                break;
            default :
                break;
        }


    };

    var bindEventListener = function(_target, events) {
        "use strict";
        for(var key in events) {
            switch (key) {
                case "start":
                    _target.addEventListener("touchstart", events[key], false);
                    break;
                case "move":
                    _target.addEventListener("touchmove", events[key], false);
                    break;
                case "end":
                    _target.addEventListener("touchend", events[key], false);
                    break;
                default :
                    break;
            }
        }
    };

    var unBindEventListener = function (_target, events) {
        "use strict";
        for(var key in events) {
            switch (key) {
                case "start":
                    _target.removeEventListener("touchstart", events[key], false);
                    break;
                case "move":
                    _target.removeEventListener("touchmove", events[key], false);
                    break;
                case "end":
                    _target.removeEventListener("touchend", events[key], false);
                    break;
                default :
                    break;
            }
        }
    };



    var initialize = function () {
        bindEventListener(wrapper, {"start": _start, "move": _move, "end": _end});
        //document.body.style.backgroundColor = "rgba(0, 0, 0, 40)";
        setTimeout(function () {
            for(var i = 0; i < $scenes.length; i++) {
                var $stages = $scenes[i].querySelectorAll(".stage");
                for(var j = 0; j < $stages.length; j++) {
                    //$stages[j].style.backgroundColor = "rgb("+Math.floor(Math.random()*255)+", "+Math.floor(Math.random()*255)+", "+Math.floor(Math.random()*255)+")";
                    //$stages[j].style.backgroundColor = "#0fffd5";
                    if(j === 0) {
                        if(i === 0) {
                            //$stages[j].style.backgroundColor = "#0fffd5";
                            updateElementTransform($stages[j], 0, 0);
                        }
                        else {
                            updateElementTransform($stages[j], bodyWidth, 0);
                        }
                    }
                    else {
                        updateElementTransform($stages[j], 0, bodyHeight);
                    }
                }
            }
        }, 1);
    };

    return {
        initialize: initialize,
        getHorizontal: function () {
            return $HORIZONTAL;
        },
        getVertical: function () {
            return $VERTICAL;
        },
        setDelay: function (_delay) {
            touchEndDelay = _delay;
        },
        getDelay: function () {
            return touchEndDelay;
        },
        slideChanged: function () {
            return slideChangeFinished;
        },
        slideTo: function (_indexh, _indexv, _direction, _duration) {
            slideTo(_indexh, _indexv, _direction, _duration);
        },
        addEventListener: function( type, listener, useCapture ) {
            if( 'addEventListener' in window ) {
                ( wrapper || document.querySelector( '#lsSliderWrapper' ) ).addEventListener( type, listener, useCapture );
            }
        },
        getVerticalSlider: function(_indexh) {
            getVerticalSlide(_indexh);
        },
        slidePause: function() {
            unBindEventListener(wrapper, {"start": _start, "move": _move, "end": _end});
        },
        slideRestart: function() {
            bindEventListener(wrapper, {"start": _start, "move": _move, "end": _end});
        },
        removeEventListener: function( type, listener, useCapture ) {
            if( 'addEventListener' in window ) {
                ( wrapper || document.querySelector( '#lsSliderWrapper' ) ).removeEventListener( type, listener, useCapture );
            }
        },
        onTouchStart: _start,
        onTouchMove: _move,
        onTouchEnd: _end,
        bindSlideToElem: function(_target) {
            bindEventListener(_target, {"start": _start, "move": _move, "end": _end});
        },
        down: function() {
            goNextVertical($HORIZONTAL, $VERTICAL, 800);
        },
        up: function() {
            goPrevVertical($HORIZONTAL, $VERTICAL, 800);
        }
    }

})();


